#include "socket_gather_write.h"

#include "pfunc.h"
#include "socket_private_acl.h"
#include "Log.h"
#ifdef WIN32
#define usleep(x) Sleep(x)
#endif

namespace G_VALUE {
	unsigned int gatherWriteUpT=0;
};

SocketGatherWrite::SocketGatherWrite(void)
	: running(true)
	, socket_acl(NULL)
	, socket_write_queue(QueueDataSingle<DataToGather>::getInstance())
{
	socket_write_queue->setQueueDesc("data_to_gchannel");
}

SocketGatherWrite::~SocketGatherWrite(void)
{
	running = false;
}

void SocketGatherWrite::setPrivateDataPtr(SocketPrivate_ACL *socket_acl_)
{
	if (NULL != socket_acl_)
	{
		socket_acl = socket_acl_;
	}	
}

void* SocketGatherWrite::run()
{
	if (NULL == socket_acl) 
	{
		CLogger::createInstance()->Log(MsgError,
			"MySocketExxWD start fail for socket_acl is NULL"
			",[%s %s %d]!"
			, __FILE__, __FUNCTION__, __LINE__);
		return 0;
	}
	unsigned long long _ipInt = 0;
	unsigned char buf[512] = { 0 };
	int len = -1;
	int ret = -1;
	while(running)
	{
		G_VALUE::gatherWriteUpT = static_cast<unsigned int>(time(NULL));
		len = this->getBuffer(_ipInt,buf);
		if (len > 0) 
		{
			bool mapIpF = true;
			ret = socket_acl->Write(_ipInt,(const char*)buf, len, mapIpF);
			if (ret != len && mapIpF) 
			{
				CLogger::createInstance()->Log(MsgInfo,
					"send data to IpLong(%lu) and MapIpF(%d): Len(%d), Ret(%d). [%s %s %d]"
					, _ipInt, static_cast<int>(mapIpF), len, ret
					, __FILE__, __FUNCTION__, __LINE__);
			}
			if (!mapIpF)
			{
				CLogger::createInstance()->Log(MsgInfo,
					"send data to IpLong(%lu) and MapIpF(%d): Len(%d), Ret(%d). [%s %s %d]"
					, _ipInt, static_cast<int>(mapIpF), len, ret
					, __FILE__, __FUNCTION__, __LINE__);
			}
			CLogger::createInstance()->Log(MsgInfo,
				"send data to IpLong(%lu) and MapIpF(%d): Len(%d), Ret(%d). [%s %s %d]"
				, _ipInt, static_cast<int>(mapIpF), len, ret
				, __FILE__, __FUNCTION__, __LINE__);
		}
		usleep(10);
	}
	return 0;
}

int SocketGatherWrite::getBuffer(unsigned long long &_ipInt, unsigned char* _buf)
{
	DataToGather it;
	if (socket_write_queue->getFirst(it)) 
	{
		try {
			_ipInt = it.ipInt;
			int idx = 0;
			unsigned char buf[512] = { 0 };
			switch (it.exeType)
			{
			case OnGet:
				buf[idx++] = 0xF5;		//查询
				break;
			case OnSet:
				buf[idx++] = 0xF6;		//设值
				break;
			default:
				return -1;
			}		
									//信息长度
			buf[idx++] = 0xf0;		//1-Len_L
			buf[idx++] = 0xf0;		//2-Len_H
			//						//时间
			//buf[idx++] = (unsigned char)(it.evtTimeS & 0xff);
			//buf[idx++] = (unsigned char)((it.evtTimeS >> 8) & 0xff);
			//buf[idx++] = (unsigned char)((it.evtTimeS >> 16) & 0xff);
			//buf[idx++] = (unsigned char)((it.evtTimeS >> 24) & 0xff);
			//buf[idx++] = (unsigned char)(it.evtTimeMS & 0xFF);		//时间毫秒值

			//pid
			buf[idx++] = (unsigned char)(it.pID & 0xff);
			buf[idx++] = (unsigned char)((it.pID >> 8) & 0xff);
			buf[idx++] = (unsigned char)((it.pID >> 16) & 0xff);
			buf[idx++] = (unsigned char)((it.pID >> 24) & 0xff);
			//pType
			buf[idx++] = (unsigned char)(it.pType & 0xff);
			//val
			unsigned char*vavch = (unsigned char*)&it.val;
			buf[idx++] = vavch[3];
			buf[idx++] = vavch[2];
			buf[idx++] = vavch[1];
			buf[idx++] = vavch[0];
			vavch = NULL;
			//taskid
			buf[idx++] = (unsigned char)(it.taskID & 0xff);
			buf[idx++] = (unsigned char)((it.taskID >> 8) & 0xff);
			buf[idx++] = (unsigned char)((it.taskID >> 16) & 0xff);
			buf[idx++] = (unsigned char)((it.taskID >> 24) & 0xff);
			//comment len
			buf[1] = static_cast<unsigned char>(idx & 0xff);
			buf[2] = static_cast<unsigned char>((idx >> 8) & 0xff);

			unsigned char m_end = 0xFF;
			memcpy(buf + idx, &m_end, 1);
			idx++;

			memset(_buf, 0, 2 * idx);
			int nLen = pyfree::code(buf, idx, _buf);
			if (!socket_write_queue->removeFirst())
			{
				CLogger::createInstance()->Log(MsgInfo,
					"removeFirstWD failed! [%s %s %d]"
					, __FILE__, __FUNCTION__, __LINE__);
			}
			
			CLogger::createInstance()->Log(MsgInfo
				, "TaskID[%lu] and down_node[2] write data,cmd(%s),time(%s)"
				",ip(%lu),pID(%d),pType(%d),val(%.3f)"
				, it.taskID, it.desc.c_str(), pyfree::getCurrentTime().c_str()
				, it.ipInt, it.pID, static_cast<int>(it.pType), it.val);
			return nLen;
		}
		catch (const std::exception& e)
		{
			CLogger::createInstance()->Log(MsgError,
				"write item info to socket failed! have error[%s]. [%s %s %d]"
				, e.what()
				, __FILE__, __FUNCTION__, __LINE__);
		}
		catch (...) 
		{
			CLogger::createInstance()->Log(MsgError,
				"write item info to socket failed! have error. [%s %s %d]"
				, __FILE__, __FUNCTION__, __LINE__);
		}
	}
	return -1;
}